package net.kleinhenz.norabase.client;

import java.util.HashSet;
import java.util.Set;

import net.kleinhenz.norabase.client.datasource.BattlegroupDS;
import net.kleinhenz.norabase.shared.model.Battlegroup;
import net.kleinhenz.norabase.shared.model.Rune;

import com.google.gwt.core.client.GWT;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.types.SelectionStyle;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.SummaryFunction;
import com.smartgwt.client.widgets.tab.Tab;

public class BattlegroupTab extends Tab {
	
	private Battlegroup<Rune> battlegroup = null;
	private ListGrid grid = null;
	private ListGridField iconField = null;
	private ListGridField nameField = null;
	private ListGridField typeField = null;
	private ListGridField startingAbilitiesStringField = null;
	private ListGridField upgradeAbilitiesStringField = null;
	private ListGridField racesField = null;
	private ListGridField classesField = null;
	private ListGridField sizeField = null;
	private ListGridField maxrngField = null;
	private ListGridField minrngField = null;
	private ListGridField spdField = null;
	private ListGridField defField = null;
	private ListGridField dmgField = null;
	private ListGridField hpField = null;
	private ListGridField expansionField = null;
	private ListGridField factionField = null;
	private ListGridField artistField = null;
	private ListGridField noraField = null;
	private ListGridField rarityField = null;
	private ListGridField ownedField = null;
	private String viewState = null;
	
	public class AvgSummary implements SummaryFunction {
		private String prefix = null;
		public AvgSummary(String prefix) {
			this.prefix = prefix;
		}
		@Override
		public Object getSummaryValue(Record[] records, ListGridField field) {
			float sum = 0;
			float count = 0;
			for (Record r : records)
				if (r.getAttributeAsInt(field.getName())!=null) {
					sum += r.getAttributeAsInt(field.getName());
					count++;
				}
			if (count>0)
				return prefix + NumberFormat.getFormat("##.#").format(sum/count);
			else
				return "";
		}
	}

	public BattlegroupTab() {
		super();
		init();
	}
	
	public BattlegroupTab(final String battlegroupId, final String name, final String viewState) {

		super(name);
		this.viewState  = viewState;
		init();
		
		if (battlegroupId!=null) {
			// retrieve battlegroup
	        BattlegroupServiceAsync service = GWT.create(BattlegroupService.class);
	        service.retrieveBattlegroup(battlegroupId, new AsyncCallback<Battlegroup<Rune>>() {
	            public void onFailure(Throwable caught) {
	            	SC.say("An error occured while retrieving battlegroup info from the server. Please try again.");
	            	return;
	            }
	            public void onSuccess(Battlegroup<Rune> result) {
	            	loadBattlegroup(result);
	            }
	        });
		} else {		
			// create the grid

			// create the battlegroup on the server
			battlegroup = new Battlegroup<Rune>();
			battlegroup.setName(name);
			setBattlegroup(battlegroup);
			BattlegroupServiceAsync service = GWT.create(BattlegroupService.class);
	        service.createBattlegroup(battlegroup, new AsyncCallback<String>() {
	            public void onFailure(Throwable caught) {
	            	SC.say("An error occured while retrieving battlegroup info from the server. Please try again.");
	            	return;
	            }
	            public void onSuccess(String result) {
	            	getBattlegroup().setId(result);
	            	populateData(viewState);
	            }
	        });
		};				
	}

	private void populateData(String viewState) {

		grid.setDataSource(new BattlegroupDS(getBattlegroup().getId()));
		grid.setFields(iconField, nameField, typeField, expansionField, factionField, startingAbilitiesStringField, upgradeAbilitiesStringField, 
				racesField, classesField, sizeField, maxrngField, minrngField, spdField, defField, dmgField,
				hpField, artistField, noraField, rarityField, ownedField);
		grid.setViewState(viewState);
		grid.fetchData();	            	
	}
	
	private void init() {
		grid = new BattlegroupGrid();
		grid.setSelectionType(SelectionStyle.SINGLE);
		grid.setShowFilterEditor(true);  
		grid.setFilterOnKeypress(true);  
		grid.setAutoFetchData(false);
		grid.setShowGridSummary(true);  
		grid.setShowGroupSummary(true); 
		grid.setEmptyMessage("No runes yet.");

		iconField = new ListGridField("icons", "Actions");
		iconField.setWidth(20);

		nameField = new ListGridField("name");  
		nameField.setIncludeInRecordSummary(false);  
		
		typeField = new ListGridField("type");  
		typeField.setIncludeInRecordSummary(true);  
		typeField.setSummaryFunction(new SummaryFunction() {
			@Override
			public Object getSummaryValue(Record[] records, ListGridField field) {
				Set<String> typeSet = new HashSet<String>();
				for (Record r : records) 
					typeSet.add(r.getAttributeAsString("type"));
				if (typeSet.size()>1)
					if (records.length==1)
						return records.length + " Rune";
					else
						return records.length + " Runes";
				else if (typeSet.contains(Rune.CHAMPION))
					if (records.length==1)
						return records.length + " Champion";
					else
						return records.length + " Champions";
				else if (typeSet.contains(Rune.EQUIPMENT))
					if (records.length==1)
						return records.length + " Equipment";
					else
						return records.length + " Equipments";
				else if (typeSet.contains(Rune.SPELL))
					if (records.length==1)
						return records.length + " Spell";
					else
						return records.length + " Spells";
				else if (typeSet.contains(Rune.RELIC))
					if (records.length==1)
						return records.length + " Relic";
					else
						return records.length + " Relics";
				else
					return "";
			}
		});

		startingAbilitiesStringField = new ListGridField("startingAbilitiesString");  
		startingAbilitiesStringField.setIncludeInRecordSummary(false);
		startingAbilitiesStringField.setHidden(true);

		upgradeAbilitiesStringField = new ListGridField("upgradeAbilitiesString");  
		upgradeAbilitiesStringField.setIncludeInRecordSummary(false);
		upgradeAbilitiesStringField.setHidden(true);

		racesField = new ListGridField("races");  
		racesField.setIncludeInRecordSummary(false);
		racesField.setHidden(true);
		
		classesField = new ListGridField("classes");  
		classesField.setIncludeInRecordSummary(false);
		classesField.setHidden(true);
		
		sizeField = new ListGridField("size");  
		sizeField.setIncludeInRecordSummary(false);
		sizeField.setHidden(true);
		
		maxrngField = new ListGridField("maxrng");
		maxrngField.setSummaryFunction(new AvgSummary("Avg Max Range: "));
		maxrngField.setIncludeInRecordSummary(false);
		
		minrngField = new ListGridField("minrng");  
		minrngField.setSummaryFunction(new AvgSummary("Avg Min Range: "));
		minrngField.setIncludeInRecordSummary(false);
		
		spdField = new ListGridField("spd");  
		spdField.setSummaryFunction(new AvgSummary("Avg Speed: "));
		spdField.setIncludeInRecordSummary(false);
		
		defField = new ListGridField("def");  
		defField.setSummaryFunction(new AvgSummary("Avg Def: "));
		defField.setIncludeInRecordSummary(false);
		
		dmgField = new ListGridField("dmg");  
		dmgField.setSummaryFunction(new AvgSummary("Avg Damage: "));
		dmgField.setIncludeInRecordSummary(false);
		
		hpField = new ListGridField("hp");  
		hpField.setSummaryFunction(new AvgSummary("Avg HP: "));
		hpField.setIncludeInRecordSummary(false);
		
		expansionField = new ListGridField("expansion");  
		expansionField.setIncludeInRecordSummary(false);
		
		factionField = new ListGridField("faction");  
		factionField.setIncludeInRecordSummary(false);

		artistField = new ListGridField("artist");  
		artistField.setIncludeInRecordSummary(false);
		artistField.setHidden(true);
		
		noraField = new ListGridField("nora");  
		noraField.setSummaryFunction(new AvgSummary("Avg Cost: "));
		noraField.setIncludeInRecordSummary(false);
		
		rarityField = new ListGridField("rarity");
		rarityField.setSummaryFunction(new AvgSummary("Avg Rarity: "));
		rarityField.setIncludeInRecordSummary(false);
		
		ownedField = new ListGridField("owned");  
		ownedField.setIncludeInRecordSummary(false);
		ownedField.setHidden(true);

		setPane(grid);
	}
	
	public void loadBattlegroup(Battlegroup<Rune> result) {
    	setBattlegroup(result);
    	populateData(viewState);
	}

	public void setBattlegroup(Battlegroup<Rune> battlegroup) {
		this.battlegroup = battlegroup;
	}

	public Battlegroup<Rune> getBattlegroup() {
		return battlegroup;
	}
	
	public void addGridClickHandler(ClickHandler handler) {
		grid.addClickHandler(handler);
	}
}
